const app = getApp();
Component({
    properties: {
        aiName: {
            type: String,
            default: ''
        },
        aiIndex: {
            type: Number,
            default: 0
        },
        activeAiIndex: {
            type: Number,
            default: 0
        },
        welcome: {
            type: Object,
            default: {}
        },
        userAvatar: {
            type: String,
            default: '/images/ic_user_logo.png'
        },
        aiAvatar: {
            type: String,
            default: '/static/img/ic_ai_logo.png'
        },
        speechIsOpen: {
            type: Boolean,
            default: true
        }
    },
    options: {
        pureDataPattern: /^_/
    },
    data: {
        group_id: 0,
        lists: null,
        message: '',
        writingText: '',
        writing: false,
        page: 1,
        pagesize: 10,
        lastViewId: 'lastViewId',
        _audioTemp: '',
        _textStacks: [],
        _textOutputSi: 0,
        _requestTask: null
    },
    observers: {
        activeAiIndex() {
            const aiIndex = this.data.aiIndex
            const activeAiIndex = this.data.activeAiIndex
            const lists = this.data.lists
            if (aiIndex >= activeAiIndex - 1 && aiIndex <= activeAiIndex + 1 && lists === null) {
                this.getHistoryMsg()
            }
        }
    },
    methods: {
        sendText(message, audio = '', audioLength = 0) {
            if (this.data.writing) {
                return
            }
            message = this.trim(message)
            if (!message) {
                app.util.message('请输入你的问题')
                return
            }
    
            if (this.data._textOutputSi) {
                clearInterval(this.data._textOutputSi)
                this.setData({
                    _textOutputSi: 0,
                    _textStacks: []
                })
            }
            let lists = this.data.lists;
            lists.push({
                user: '我',
                message: message,
                audio: audio,
                audio_length: Math.ceil(audioLength / 1000)
            });
            this.setMessage('')
            this.setData({
                writing: true,
                lists: lists
            })
            this.scrollToBottom()
    
            // stream
            const textOutputSi = setInterval(() => {
                if (this.data._textStacks.length > 0) {
                    const char = this.data._textStacks.shift()
                    this.setData({
                        writingText: this.data.writingText + char
                    })
                    if (audio) {
                        this.setData({
                            audioTemp: this.data.audioTemp + char
                        })
                        if (char == "\n") {
                            this.triggerEvent('addToPlay', {
                                text: this.data._audioTemp,
                                aiIndex: this.data.aiIndex,
                                msgIndex: this.data.lists.length
                            })
                            this.setData({
                                _audioTemp: ''
                            })
                        } else {
                            this.setData({
                                _audioTemp: this.data._audioTemp + char
                            })
                        }
                    }
                    
                    this.scrollToBottom()
                } else if (!this.data.writing) {
                    clearInterval(this.data._textOutputSi)
                    this.setData({
                        _textOutputSi: 0
                    })
                    if (audio) {
                        this.triggerEvent('addToPlay', {
                            text: this.data._audioTemp,
                            aiIndex: this.data.aiIndex,
                            msgIndex: this.data.lists.length
                        })
                        this.triggerEvent('addToPlay', {
                            text: '[end]',
                            aiIndex: this.data.aiIndex,
                            msgIndex: this.data.lists.length
                        })
                        this.setData({
                            _audioTemp: ''
                        })
                    }
                    if (this.data.writingText) {
                        lists.push({
                            user: 'AI',
                            message: this.data.writingText,
                            playing: audio ? true : false
                        })
                        this.setData({
                            lists: lists
                        })
                    }
                    this.setData({
                        writingText: ''
                    });
                    this.scrollToBottom();
                }
            }, 30)
            this.setData({
                _textOutputSi: textOutputSi
            })
    
            // 网络请求
            const _this = this;
            const requestTask = wx.request({
                url: app.siteinfo.host + '/web.php/chat/sendText',
                timeout: 300000,
                responseType: 'text',
                method: 'POST',
                enableChunked: true, //配置这里
                header: {
                    'Content-Type': 'application/json',
                    'X-Site': wx.getStorageSync('sitecode'),
                    'X-Token': wx.getStorageSync('token')
                },
                data: {
                    ai: _this.data.aiName,
                    message: message,
                    audio: audio,
                    audio_length: audioLength
                },
                success: res => {
                    _this.setData({
                        writing: false
                    });
                },
                fail: error => {
                    _this.setData({
                        writing: false
                    });
                }
            })
            // 这里监听消息
            requestTask.onChunkReceived(function (res) {
                // ArrayBuffer to Text
                const uint8Array = new Uint8Array(res.data);
                let char = String.fromCharCode.apply(null, uint8Array);
                char = decodeURIComponent(escape(char));
    
                if (char.indexOf('[error]') !== -1) {
                    lists.pop()
                    _this.setData({
                        writing: false,
                        writingText: '',
                        lists: lists
                    })
                    _this.setMessage(message)
                    clearInterval(_this.data._textOutputSi)
                    _this.setData({
                        _textOutputSi: 0
                    })
    
                    const error = char.replace('[error]', '')
                    if (error.indexOf('请登录') !== -1) {
                        app.util.toLogin(error)
                    } else if (error.indexOf('请充值') !== -1) {
                        let pay_type = _this.isGpt4(_this.data.aiName) ? 'model4' : 'vip'
                        app.util.toPay(pay_type, error)
                    } else {
                        app.util.message(error, 'error');
                    }
                    return
                }
    
                _this.setData({
                    writing: true
                })
                let textStacks = _this.data._textStacks
                for (var i = 0; i < char.length; i++) {
                    textStacks.push(char[i])
                    _this.setData({
                        _textStacks: textStacks
                    })
                }
            })
            this.setData({
                _requestTask: requestTask
            })
        },
        stopFetch() {
            this.data._requestTask.abort();
            this.setData({
                writing: false,
                _textStacks: [],
                _audioTemp: ''
            })
            let lists = this.data.lists
            const writingText = this.data.writingText
            this.triggerEvent('stopPlay')
    
            setTimeout(() => {
                if (!writingText) {
                    lists.pop()
                    this.setData({
                        lists: lists
                    })
                }
            }, 60)
        },
        retry(e) {
            const _this = this;
            const index = e.currentTarget.dataset.index;
            if (!_this.data.lists[index - 1]) {
                return;
            }
            wx.showModal({
                title: '提示',
                content: '确定重新回答吗？',
                success: function (res) {
                    if (res.confirm) {
                        const item = _this.data.lists[index - 1]
                        const message = item.message
                        const audio = item.audio
                        const audioLength = parseInt(item.audio_length)
                        _this.sendText(message, audio ? audio : '', audioLength ? audioLength * 1000 : 0)
                    }
                }
            })
        },
        sendConfirm() {
            setTimeout(() => {
                this.sendText()
            }, 50)
        },

        switchPlay(e) {
            let msgIndex = e.currentTarget.dataset.index
            let lists = this.data.lists
            let item = lists[msgIndex]
            if (item.playing) {
                this.triggerEvent('stopPlay')
            } else {
                this.triggerEvent('startPlay', {
                    msgIndex: msgIndex,
                    aiIndex: this.data.aiIndex
                })
            }
        },
        setPlayStart(index) {
            let lists = this.data.lists
            if (!lists[index]) {
                return
            }
            lists[index].playing = true
            this.setData({
                lists: lists
            })
        },
        setPlayStop(index) {
            let lists = this.data.lists
            if (!lists[index]) {
                return
            }
            lists[index].playing = false
            this.setData({
                lists: lists
            })
        },
        switchPlayAudio(e) {
            let msgIndex = e.currentTarget.dataset.index
            let lists = this.data.lists
            let item = lists[msgIndex]
            if (this.data.writing) {
                app.util.message('AI输出中，请稍候')
                return
            }
            if (!item.playing) {
                if (item.audio) {
                    this.triggerEvent('playAudio', {
                        msgIndex: msgIndex,
                        aiIndex: this.data.aiIndex,
                        audio: item.audio
                    })
                }
            } else {
                this.triggerEvent('stopPlay')
            }
        },

        getHistoryMsg() {
            app.util.request({
                    url: '/chat/getHistoryMsg',
                    data: {
                        ai: this.data.aiName,
                        page: this.data.page,
                        pagesize: this.data.pagesize
                    }
                })
                .then((res) => {
                    this.setData({
                        lists: res.data.list
                    })
                    setTimeout(() => {
                        this.scrollToBottom()
                    }, 300)
                });
        },
        scrollToBottom() {
            setTimeout(() => {
                this.setData({
                    lastViewId: 'lastViewId'
                })
            }, 300)
        },
        copyText(e) {
            const index = e.currentTarget.dataset.index
            const text = this.trim(this.data.lists[index].message)
            wx.setClipboardData({
                data: text
            })
        },
        trim(str) {
            if (str) {
                str = str.replace(/(^\s*)|(\s*$)/g, '');
            }
            return str
        },
        setMessage(e) {
            const message  = e.detail ? e.detail : e
            this.triggerEvent('setMessage', message)
        },
        isGpt4(name) {
            return ['openai4', 'azure_openai4', 'wenxin4', 'claude2', 'hunyuan4'].includes(name)
        },
    }
})